package com.telnetnz.ticketdesk.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.telnetnz.ticketdesk.bean.OperationLog;
import com.telnetnz.ticketdesk.bean.misc.OperationLogObject;
import com.telnetnz.ticketdesk.common.config.SpringContext;
import com.telnetnz.ticketdesk.dao.entity.OperationLogEntity;
import com.telnetnz.ticketdesk.dao.wrapper.OperationLogWrap;

public class OperationLogService
{
	public static final String[] ORDER_BY = OperationLogWrap.ORDER_BY;
	public static final int ORDERBY_TIME = 0;
	public static final int ORDERBY_OBJID = 1;

	public static final String[] ORDER = OperationLogWrap.ORDER;

	public static final String[] OBJECT_TYPES = new String[]{
		"user", "member", "project", "ticket", "ticketcomment"
	};
	public static final int OBJECT_TYPE_USER = 0;
	public static final int OBJECT_TYPE_MEMBER = 1;
	public static final int OBJECT_TYPE_PROJECT = 2;
	public static final int OBJECT_TYPE_TICKET = 3;
	public static final int OBJECT_TYPE_TICKETCOMMENT = 4;
	public static final int OBJECT_TYPE_TAG = 5;
	public static final int OBJECT_TYPE_TEMPLATE = 6;
	public static final int OBJECT_TYPE_ATTACHMENT = 7;

	private static Logger logger = Logger.getLogger(OperationLogService.class);

	public static long getOperationLogSize()
	{
		return getWrap().countAll();
	}

	public static List<OperationLog> getLogsByPageAndCondition(
			int start,
			int limit,
			int orderby,
			int order,
			long userId,
			int objectType,
			long objectId,
			String action,
			Date createAfter,
			Date createBefore)
	{
		List<OperationLogEntity> entities = getWrap().selectByPageAndCondition(
				start, limit, orderby, order, userId, objectType, objectId, action, createAfter, createBefore);
		return adaptList(entities);
	}

	public static long countByCondition(
			long userId,
			int objectType,
			long objectId,
			String action,
			Date createAfter,
			Date createBefore)
	{
		return getWrap().countByCondition(
				userId, objectType, objectId, action, createAfter, createBefore);
	}

	public static OperationLog getLog(long logId)
	{
		OperationLogEntity entity = getWrap().select(logId);
		return OperationLog.adapt(entity);
	}

	public static void addLog(
			int objectType, 
			long objectId, 
			long userId, 
			String action, 
			Map<String, List<String>> parametersMap)
	{
		OperationLog log = new OperationLog();
		log.setObjectType(objectType);
		log.setObjectId(objectId);
		log.setUserId(userId);
		log.setAction(action);
		log.setParametersMap(parametersMap);
		log.setTime(new Date());
		getWrap().insert(log.toEntity());
	}

	public static OperationLogObject getObject(int objectType, long objectId)
	{
		OperationLogObject obj;
		switch(objectType)
		{
			case OBJECT_TYPE_USER:
				obj = UserService.getUser(objectId);break;
			case OBJECT_TYPE_MEMBER:
				obj = MemberService.getMember(objectId);break;
			case OBJECT_TYPE_PROJECT:
				obj = ProjectService.getProject((int)objectId);break;
			case OBJECT_TYPE_TICKET:
				obj = TicketService.getTicket(objectId);break;
			case OBJECT_TYPE_TICKETCOMMENT:
				obj = TicketCommentService.getTicketComment(objectId);break;
			case OBJECT_TYPE_TAG:
				obj = TagService.getTag(objectId);break;
			default:
				obj = null;
		}
		return obj;
	}

	public static Map<String, List<String>> createSimpleDiff(String key, String[] content)
	{
		Map<String, List<String>> diff = new HashMap<String, List<String>>();
		diff.put(key, Arrays.asList(content));
		return diff;
	}

	private static List<OperationLog> adaptList(List<OperationLogEntity> entities)
	{
		List<OperationLog> operationLogList = new ArrayList<OperationLog>();
		if (entities != null && entities.size() > 0)
		{
			for (int i = 0; i < entities.size(); i++)
			{
				OperationLog operationLog = OperationLog.adapt(entities.get(i));
				if (operationLog != null)
					operationLogList.add(operationLog);
			}
		}
		return operationLogList;
	}

	private static OperationLogWrap getWrap()
	{
		return SpringContext.getOperationLogWrap();
	}

}
